package com.corpdata.activiti.service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.corpdata.activiti.dao.ProcessMapper;
import com.corpdata.activiti.entity.ProcessInfo;
import com.corpdata.activiti.utils.ActivitiUtils;
import com.corpdata.common.result.DataTable;
import com.corpdata.common.result.Result;
import com.corpdata.common.utils.ResultUtil;
import com.corpdata.common.utils.StringUtils;

@Service
public class ProcessService {

	@Autowired
	private ProcessMapper processMapper;

	@Autowired
	private RuntimeService runtimeService;

	@Autowired
	ProcessEngine processEngine;

	@Autowired
	private TaskService taskService;

	@Autowired
	private RepositoryService repositoryService;

	/**
	 * 查询流程列表
	 * @param dt
	 * @return
	 */
	public DataTable<ProcessInfo> getProcessByPage(DataTable dt) {
		
		ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery().latestVersion();
		if(dt.getSearchParams()!=null){
			String category = (String) dt.getSearchParams().get("category");
			if (StringUtils.isNotBlank(category)) {
				query.processDefinitionCategory(category);
			}
		}
		
		dt.setTotal(((Long) query.count()).intValue());
		query.listPage((dt.getPage() - 1) * dt.getSize(), dt.getSize()).stream()
				.forEach(processDefinition -> {
					Deployment deployment = repositoryService.createDeploymentQuery()
							.deploymentId(processDefinition.getDeploymentId()).singleResult();
					dt.getRows().add(ActivitiUtils.toProcessVO(processDefinition, deployment));
				});
		
		dt.setRows((List<ProcessInfo>) dt.getRows().stream()
				.sorted(Comparator.comparing(ProcessInfo::getDeploymentTime).reversed()).collect(Collectors.toList()));
		return dt;
	}

	/**
	 * 启动流程实例
	 * @param key 流程key
	 * @return
	 */
	public Result startProcessInstance(String key,String userId){
		//参数
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("userId", userId);//启动流程首节点参与人 默认给自己
		variables.put("new_property_1", "哈哈");
		
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(key,variables);
		
		System.out.println("流程梳理所属流程定义id："   
	            + processInstance.getProcessDefinitionId());  
	    System.out.println("流程实例的id：" + processInstance.getProcessInstanceId());  
	    System.out.println("流程实例的执行id：" + processInstance.getId());  
	    System.out.println("流程当前的活动（结点）id：" + processInstance.getActivityId());  
	    System.out.println("业务标识：" + processInstance.getBusinessKey());
	    
	    //获取当前流程实例任务对象
	    Task task = taskService.createTaskQuery()
	    	.processInstanceId(processInstance.getProcessInstanceId())
	    	.taskDefinitionKey(processInstance.getActivityId())
	    	.executionId(processInstance.getId())
	    	.singleResult();
	    //任务属性输出到客户端
	    Map<String,Object> taskMap = new HashMap<String,Object>();
	    taskMap.put("formKey", task.getFormKey());
	    taskMap.put("taskName", task.getName());
	    taskMap.put("taskId", task.getId());
	    
		return ResultUtil.success(taskMap);
	}
	
	/**
	 * 按用户获取所有待办任务
	 * @param dt
	 * @return
	 */
	public DataTable<Task> getTaskByUser(DataTable dt,String userId){
		TaskService taskService = processEngine.getTaskService();
		List<Task> tasks = taskService.createTaskQuery()
				.taskAssignee(userId)//按用户查询
				.listPage((dt.getPage() - 1) * dt.getSize(), dt.getSize());//分页
		
		List<Map<String,Object>> rows = new ArrayList<Map<String,Object>>();
		for (Task task : tasks) {
			Map<String,Object> m = new HashMap<String,Object>();
			m.put("name", task.getName());
			m.put("assignee", task.getAssignee());
			m.put("category", task.getCategory());
			m.put("createTime", task.getCreateTime());
			m.put("description", task.getDescription());
			m.put("dueDate", task.getDueDate());
			m.put("executionId", task.getExecutionId());
			m.put("formKey", task.getFormKey());
			m.put("id", task.getId());
			m.put("owner", task.getOwner());
			m.put("parentTaskId", task.getParentTaskId());
			m.put("priority", task.getPriority());
			m.put("processDefinitionId", task.getProcessDefinitionId());
			m.put("processInstanceId", task.getProcessInstanceId());
			m.put("taskDefinitionKey", task.getTaskDefinitionKey());
			m.put("tenantId", task.getTenantId());
			m.put("processVariables", task.getProcessVariables());
			m.put("taskLocalVariables", task.getTaskLocalVariables());
			rows.add(m);
		}
		dt.setTotalAndRows(tasks.size(), rows);
		return dt;
	}
	
	/**
	 * 执行任务
	 * @return
	 */
	public Result completeTask(String taskId){
		Map<String, Object> taskVariables = new HashMap<String, Object>();
		taskVariables.put("new_property_2", "拜拜");
		taskVariables.put("userId", "admin");
		TaskService taskService = processEngine.getTaskService();
		//taskService.setAssignee(taskId, userId);
		taskService.complete(taskId, taskVariables);
		return ResultUtil.success();
	}
	
	/**
	 * 按用户获取流程实例
	 * @param dt
	 * @return
	 */
	public DataTable<ProcessInstance> getProcessInstanceByUser(DataTable dt) {
		String userId = "";
		if(dt.getSearchParams()!=null){
			userId = (String) dt.getSearchParams().get("userId");
		}
		ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery().involvedUser(userId);
		
		dt.setTotal(((Long) query.count()).intValue());
		query.listPage((dt.getPage() - 1) * dt.getSize(), dt.getSize());

//				.forEach(ProcessInstance -> {
//					ProcessInstance deployment = repositoryService.createDeploymentQuery()
//							.deploymentId(processDefinition.getDeploymentId()).singleResult();
//					dt.getRows().add(ActivitiUtils.toProcessVO(processDefinition, deployment));
//				});
		
		dt.setRows(query.list());
		return dt;
	}
	
	public List<Map<String, Object>> getList(String id) {
		
		// runtimeService.get
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userid", "kermit");
		// runtimeService.set
		ProcessInstance ins = runtimeService.startProcessInstanceById(id, params);
		System.out.println(ins.getName());
		System.out.println(ins.getProcessVariables());
		System.out.println(JSON.toJSON(ins));
		// System.out.println(processEngine.getIdentityService().get);
		// Model m = processEngine.getRepositoryService().getModel("1783");
		// System.out.println(m.toString());

		// TaskQuery taskQuery =
		// taskService.createTaskQuery().taskCandidateOrAssigned("Kermit");//自己办理或在该节点对应工作组中的流程 
		// System.out.println(taskQuery.count());

		// .createTaskQuery().taskCandidateOrAssigned("");

		return processMapper.selectAll();
	}

	public String getDef() {
		BpmnModel bm = repositoryService.getBpmnModel("myProcess");
		System.out.println(bm);
		return "";
	}

	//部署流程
	public String deployed() {
		// deployments
		repositoryService.createDeployment().name("myProcess").addClasspathResource("processes/MyProcess1.bpmn")
				.deploy();
		String rs = "Number of process definitions: " + repositoryService.createProcessDefinitionQuery().count();
		return rs;
	}

	public String getTasks() {
		List<Task> tasks = taskService.createTaskQuery().taskAssignee("kermit").orderByDueDate().asc().list();
		System.out.println(tasks.toString());
		return "ok";
	}

	public String startwf() {
		String id = "myProcess";
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("userid", "kermit");
		// runtimeService.set
		// ProcessInstance ins = runtimeService.startProcessInstanceById(id,
		// params);
		ProcessInstance ins = runtimeService.startProcessInstanceByKey(id, params);
		System.out.println(ins.getName());
		System.out.println(ins.getProcessVariables());
		System.out.println(JSON.toJSON(ins));
		return ins.getName();
	}
}
